package com.snk.interceptor;


import com.snk.common.config.Cache;
import com.snk.common.utils.CookieUtil;
import com.snk.common.utils.ObjectMapperUtil;
import com.snk.pojo.User;
import com.snk.util.UserThreadLocal;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import org.springframework.web.servlet.HandlerInterceptor;


import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

@Component  //将拦截器交给spring容器管理
public class UserInterceptor implements HandlerInterceptor {

    private static final String SNK_TICKET="SNK_TICKET";

    /**
     * 返回值说明:
     *      1.false  表示拦截  一般都要配合重定向的方式使用.
     *      2.true   表示放行
     *
     * 如何实现业务:
     *      判断用户是否登录:   Cookie数据  检查redis中的数据.
     *      重定向到系统登录页面.
     *
     * @param request
     * @param response
     * @param handler
     * @return
     * @throws Exception
     */
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        //1.校验Cookie中是否有结果
        Cookie cookie = CookieUtil.getCookie(request, SNK_TICKET);

        //2.校验Cookie是否有效
        if(cookie != null){
            String userIdJson = cookie.getValue();
            if(StringUtils.hasLength(userIdJson)){
                    //利用Request对象将数据进行传递  最为常见的参数传递的方式
                    request.setAttribute(SNK_TICKET, userIdJson);

                    //ThreadLocal机制线程局部变量
                    UserThreadLocal.setUser(userIdJson);

                    //表示用户登录过  直接返回true
                    return true;
            }
            //没有结果,则cookie数据有误,应该删除
            CookieUtil.addCookie(response, SNK_TICKET, "", "/", "jt.com", 0);
        }

        //3.如果数据为空,则重定向到系统首页
        response.sendRedirect("/login.html");
        return false;   //表示拦截....
    }


    //为了防止内存泄露,将多余的数据删除
    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        //移除request对象
        request.removeAttribute(SNK_TICKET);
        //移除threadLocal数据
        UserThreadLocal.remove();
    }
}
